/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Raytracing.BRDF;


import Raytracing.Constants;
import Raytracing.Ray;
import Raytracing.Sampling;
import Raytracing.Shaders.TextureProvider;
import processing.core.PVector;

/**
 *
 * @author Matt
 */
public class DiffuseBRDF implements BRDF {

    private TextureProvider Rd;

    public DiffuseBRDF(TextureProvider Rd) {
        this.Rd = Rd;
    }

    public PVector getReflectance(PVector incoming, PVector outgoing, PVector normal, float tu, float tv, PVector u, PVector v) {

        PVector col = new PVector();

        Rd.getColor(tu, tv, col);


        
        //float cosInNorm = (normal.dot(incoming));
        //float cosOutNorm = (normal.dot(outgoing));
        
        float cosInNorm = incoming.z;
        float cosOutNorm = outgoing.z;        
        
       
        //diffuse
        float ret = 28.f / (Constants.PI * 23.f);
        float in = 1.f - (cosInNorm / 2.f);
        in = in * in * in * in * in;
        in = 1.f - in;
        float out = 1.f - (cosOutNorm / 2.f);
        out = out * out * out * out * out;
        out = 1.f - out;
        PVector bd = PVector.mult(col, ret * in * out);

               
        return bd;
    }

    public float sampleReflectance(PVector outgoing, Ray sample,
            PVector normal, PVector BRDF,
            float tu, float tv, PVector u, PVector v,
            float u1, float u2) {

        Sampling.cosineSampleHemisphere(sample.direction, u1, u2);
        BRDF.set(getReflectance(sample.direction, outgoing, normal, tu, tv, u, v));
        
        sample.bounceType = Ray.DIFFUSE;
        
        return 1.f / Constants.PI;
    }
}
